﻿using System.IO;
using FizzBuzz;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;

namespace TestProject2
{
    
    
    /// <summary>
    ///This is a test class for FizzBuzzutilityTest and is intended
    ///to contain all FizzBuzzutilityTest Unit Tests
    ///</summary>
    [TestClass()]
    public class FizzBuzzutilityTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for GenerateFizzBuzz
        ///</summary>
        [TestMethod()]
        public void GenerateFizzBuzzTest()
        {
            int startnumber = 1; 
            int endnumber = 15; 
            string fizztoken = "Fizz"; 
            string buzztoken = "Buzz"; 
            List<string> expected = new List<string>()
                                        {
                                            "1","2","Fizz","4","Buzz","Fizz","7","8",
                                            "Fizz","Buzz","11","Fizz","13","14","FizzBuzz"
                                        }; 
            List<string> actual;
            actual = FizzBuzzutility.GenerateFizzBuzz(startnumber, endnumber, fizztoken, buzztoken);
            Assert.AreEqual(expected.Count, actual.Count);
            CollectionAssert.AreEqual(expected,actual);
        }

        [TestMethod()]
        public void GenerateFizzBuzzTestForDifferentFizzBuzzTokens()
        {
            int startnumber = 1;
            int endnumber = 15;
            string fizztoken = "Head";
            string buzztoken = "Spring";
            List<string> expected = new List<string>()
                                        {
                                            "1","2","Head","4","Spring","Head","7","8",
                                            "Head","Spring","11","Head","13","14","HeadSpring"
                                        };
            List<string> actual;
            actual = FizzBuzzutility.GenerateFizzBuzz(startnumber, endnumber, fizztoken, buzztoken);
            Assert.AreEqual(expected.Count, actual.Count);
            CollectionAssert.AreEqual(expected, actual);
        }

        /// <summary>
        /// TODO : More research to validate Screen output
        /// </summary>
        [TestMethod()]
        public void TestConsoleApplication()
        {
           using (StringWriter sw = new StringWriter() )
           {
               Console.SetOut(sw);

               using (StringReader sr = new StringReader(string.Format("1{0}3{0}1{0}Fizz{0}Buzz", Environment.NewLine)))
               {
                   Console.SetIn(sr);

                   FizzBuzzConsole.Program.Main(new string[] {});

                   string expected =
                       string.Format(
                           "Enter start number{0}Enter end number{0}Select the destination. Press 1 for Screen or 2 for File.{0}Enter Fizz token <optional>{0}Enter Buzz token <optional>{0}" +
                           "1{0}2{0}Fizz{0}"
                           ,Environment.NewLine);

                   Assert.AreEqual(expected,sw.ToString(),true);
               }
           }
        }

        /// <summary>
        /// TODO : More research to validate Screen output
        /// </summary>
        [TestMethod()]
        public void TestShouldAcceptValidStartNumber()
        {
            using (StringWriter sw = new StringWriter())
            {
                Console.SetOut(sw);

                using (StringReader sr = new StringReader(string.Format("start{0}3{0}1", Environment.NewLine)))
                {
                    Console.SetIn(sr);

                    FizzBuzzConsole.Program.Main(new string[] { });

                    string expected =
                        string.Format(
                            "Enter start number{0}Enter end number{0}Select the destination. Press 1 for Screen or 2 for File.{0}Please enter valid number for 1st input.{0}"
                            , Environment.NewLine);
                    Assert.AreEqual(expected, sw.ToString(), true);
                }
            }
        }

        [TestMethod()]
        public void TestShouldAcceptValidEndNumber()
        {
            using (StringWriter sw = new StringWriter())
            {
                Console.SetOut(sw);

                using (StringReader sr = new StringReader(string.Format("1{0}end{0}1", Environment.NewLine)))
                {
                    Console.SetIn(sr);

                    FizzBuzzConsole.Program.Main(new string[] { });

                    string expected =
                        string.Format(
                            "Enter start number{0}Enter end number{0}Select the destination. Press 1 for Screen or 2 for File.{0}Please enter valid number for 2nd input.{0}"
                            , Environment.NewLine);
                    Assert.AreEqual(expected, sw.ToString(), true);
                }
            }
        }

        [TestMethod()]
        public void TestShouldCreateFile()
        {
            using (StringWriter sw = new StringWriter())
            {
                Console.SetOut(sw);

                using (StringReader sr = new StringReader(string.Format("1{0}5{0}2{0}Fizz{0}Buzz", Environment.NewLine)))
                {
                    Console.SetIn(sr);
                    FizzBuzzConsole.Program.Main(new string[] { });
                    string[] s = File.ReadAllLines(@"C:\out.txt");
                    string[] expected = {"1", "2", "Fizz", "4", "Buzz"};
                    Assert.AreEqual(s.Length,expected.Length);
                }
            }
        }
    }
}
